/*
 * @Author: Wangjun
 * @Date: 2021-07-19 19:31:56
 * @LastEditTime: 2025-10-06 10:04:17
 * @LastEditors: wangjun haodreams@163.com
 * @Description:
 * @FilePath: \golib\autoroute\minauth\user.go
 * hnxr
 */
package minauth

import (
	"encoding/json"
	"os"

	"gitee.com/haodreams/golib/session"
)

// var users *Users

const (
	userFilePath = "user.dat"
)

func Init(defaultUser func() (user, passwd string)) {
	au := GetDefautlAuth()
	au.users = new(Users)
	au.users.init(defaultUser)
}

/**
 * @description: 保存账号信息
 * @return {*}
 */
func Save() (err error) {
	au := GetDefautlAuth()
	if au.users != nil {
		err = au.users.Save()
	}
	return
}

func GetUsers() *Users {
	return GetDefautlAuth().users
}

type User struct {
	Name   string //用户名
	Level  int    //级别
	Alias  string //别名
	Pwd    string //密码
	Remark string //备注
	Roles  []string
	roles  *Roles
}

func (m *User) GetRoles() *Roles {
	return m.roles
}

func (u *User) GetName() string {
	return u.Name
}

func (m *User) GetHome() string {
	if m.roles != nil {
		return m.roles.GetHome()
	}
	return ""
}

func (m *User) AddRole(role *Role) *User {
	if m.roles == nil {
		m.roles = NewRoles()
	}
	m.roles.AddRole(role)
	return m
}

func (u *User) GetPassword() string {
	return u.Pwd
}

func (u *User) SetPassword(password string) {
	u.Pwd = password
}

func (m *User) GetLevel() int {
	return m.Level
}

func (m *User) SetLevel(level int) *User {
	m.Level = level
	return m
}

func (u *User) GetAlias() string {
	return u.Alias
}

func (u *User) SetAlias(alias string) session.Userer {
	u.Alias = alias
	return u
}

type Users struct {
	users   []*User
	mapUser map[string]*User
}

func NewUsers() *Users {
	m := new(Users)
	m.Init()
	return m
}

func (m *Users) Save() (err error) {
	data, err := json.MarshalIndent(m.users, "", " ")
	if err != nil {
		return
	}
	err = os.WriteFile(userFilePath, data, 0644)
	return
}

func (m *Users) Init(paths ...string) {
	path := userFilePath
	if len(paths) > 0 {
		path = paths[0]
	}
	m.mapUser = map[string]*User{}
	data, err := os.ReadFile(path)
	if err != nil {
		return
	}
	err = json.Unmarshal(data, &m.users)
	if err != nil {
		return
	}
	for _, user := range m.users {
		user.roles = NewRoles()
		m.mapUser[user.Name] = user
	}
}

func (m *Users) init(defaultUser func() (user, passwd string)) {
	m.Init()

	user, passwd := defaultUser()
	if user == "" || passwd == "" {
		return
	}
	m.Create(user, passwd, true)
}

func (m *Users) GetUser(name string) session.Userer {
	user := m.mapUser[name]
	if user == nil {
		return nil
	}
	return user
}

func (m *Users) AddUser(name, pwd string, needHash bool) {
	user := m.mapUser[name]
	if needHash {
		pwd = Hash(pwd)
	}
	if user == nil {
		user = new(User)
		user.Name = name
		m.mapUser[user.Name] = user
		m.users = append(m.users, user)
	}
	user.Pwd = pwd
}

func (m *Users) Create(name, pwd string, needHash bool) *User {
	user := m.mapUser[name]
	if user != nil {
		return user
	}
	user = new(User)
	user.Name = name
	if needHash {
		pwd = Hash(pwd)
	}
	user.Pwd = pwd
	m.mapUser[user.Name] = user
	m.users = append(m.users, user)
	return user
}

// 初始化用户角色
func (m *Users) InitRoles(mapRole map[string]*Role) *Users {
	for _, user := range m.users {
		for _, role := range user.Roles {
			re := mapRole[role]
			if re != nil {
				user.AddRole(re)
			}
		}
	}
	return m
}
